package com.slx.sthq.config;


import com.slx.sthq.config.properties.MinioProperties;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.SetBucketPolicyArgs;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;
import java.util.List;


@Slf4j
@AutoConfiguration
@EnableCaching
@EnableConfigurationProperties(MinioProperties.class)
public class MinioConfiguration {

    @Autowired
    private MinioProperties minioProperties;

    @Bean
    public MinioClient minioClient() {
        MinioClient minioClient = MinioClient.builder().endpoint(minioProperties.getUrl()).credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey()).build();
        minioClient.setTimeout(minioProperties.getConnectTimeout(), minioProperties.getWriteTimeout(), minioProperties.getReadTimeout());
        if (minioProperties.isCheckBucket()) {

            String[] bucketNameList = minioProperties.getBucketName().split(",");
            //String bucketName = minioProperties.getBucketName();
            for (String bucketName : bucketNameList) {
                log.info("校验桶 {} 是否已存在", bucketName);
                //修改访问策略
                if (isBucketNotExists(bucketName, minioClient) && minioProperties.isCreateBucket()) {
                    createBucket(bucketName, minioClient);
                    log.info("桶 {} 创建成功", bucketName);
                } else {
                    log.info("桶 {} 已存在, MinIO客户端连接成功", bucketName);
                }
                setAccessPolicyPublic(minioClient, bucketName);
            }
        }
        return minioClient;
    }

    @SneakyThrows
    public void setAccessPolicyPublic(MinioClient minioClient, String bucket) {
        try {
            //String policy = "{\n" + "\t\"Version\": \"2012-10-17\",\n" + "\t\"Statement\": [\n" + "\t\t{\n" + "\t\t\t\"Action\": [\"s3:GetObject\"],\n" + "\t\t\t\"Effect\": \"Allow\",\n" + "\t\t\t\"Principal\": \"*\",\n" + "\t\t\t\"Resource\": [\"arn:aws:s3:::" + bucket + "/*\"]\n" + "\t\t}\n" + "\t]\n" + "}";
            String policy = "{\"Version\":\"2012-10-17\"," +
                    "\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":" +
                    "{\"AWS\":[\"*\"]},\"Action\":[\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"," +
                    "\"s3:GetBucketLocation\"],\"Resource\":[\"arn:aws:s3:::" + bucket +
                    "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:PutObject\",\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\"],\"Resource\":[\"arn:aws:s3:::" +
                    bucket +
                    "/*\"]}]}";
            minioClient.setBucketPolicy(
                    SetBucketPolicyArgs.builder().
                            bucket(bucket).
                            config(policy).
                            build());
            log.info("修改桶【{}】的策略为公开成功", bucket);
        } catch (Exception e) {
            log.error("修改桶【{}】的策略失败", bucket);
        }

    }

    @SneakyThrows
    private boolean isBucketNotExists(String bucketName, MinioClient minioClient) {
        return !minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
    }

    @SneakyThrows
    private void createBucket(String bucketName, MinioClient minioClient) {
        minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
    }

}
